using System;
using EPiServer.Common;
using EPiServer.Common.Queries;
using EPiServer.Common.Security;
using EPiServer.Community.Expert;
using EPiServer.Community.Expert.Queries;

namespace EPiAbstractions.Community.Expert
{
    public interface IExpertHandlerFacade
    {
        ExpertBase AddExpert(ExpertBase expert);

        void UpdateExpert(ExpertBase expert);

        void RemoveExpert(ExpertBase expert);

        ExpertBase GetExpert(Int32 id);

        ExpertBase GetExpert(Guid loginGuid);

        ExpertBase GetExpert(IUser user);

        ExpertCollection GetExperts(Int32 page, Int32 pageSize, ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, Int32 page, Int32 pageSize, ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, Int32 page, Int32 pageSize, out Int32 totalItems, ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, ExpertStatus expertStatus, Int32 page, Int32 pageSize, ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, ExpertStatus expertStatus, Int32 page, Int32 pageSize, out Int32 totalItems,
                                    ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, NullValueAction siteNullAction, ExpertStatus expertStatus, Int32 page,
                                    Int32 pageSize, ExpertSortOrder[] order);

        ExpertCollection GetExperts(SiteCollection sites, NullValueAction siteNullAction, ExpertStatus expertStatus, Int32 page,
                                    Int32 pageSize, out Int32 totalItems, ExpertSortOrder[] order);

        Question AddQuestion(Question question);

        void UpdateQuestion(Question question);

        void RemoveQuestion(Question question);

        Question GetQuestion(Int32 id);

        QuestionCollection GetQuestions(Int32 page, Int32 pageSize, QuestionSortOrder[] order);

        QuestionCollection GetQuestions(Int32 page, Int32 pageSize, out Int32 totalItems, QuestionSortOrder[] order);

        QuestionCollection GetQuestions(QuestionStatus questionStatus, Int32 page, Int32 pageSize, QuestionSortOrder[] order);

        QuestionCollection GetQuestions(QuestionStatus questionStatus, Int32 page, Int32 pageSize, out Int32 totalItems,
                                        QuestionSortOrder[] order);

        void AddQuestionRelation(Question question, Question relatedQuestion);

        void RemoveQuestionRelation(Question question, Question relatedQuestion);

        QuestionCollection GetRelatedQuestions(Question question);

        QuestionCollection GetRelatingQuestions(Question question);

        QuestionCollection GetNotRelatedQuestions(Question question, QuestionStatus status, Int32 page, Int32 pageSize,
                                                  QuestionSortOrder[] order);

        QuestionCollection GetNotRelatedQuestions(Question question, QuestionStatus status, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                  QuestionSortOrder[] order);

        AssignedQuestion AddAssignedQuestion(AssignedQuestion assignedQuestion);

        void RemoveAssignedQuestion(AssignedQuestion assignedQuestion);

        AssignedQuestion GetAssignedQuestion(Int32 id);

        AssignedQuestionCollection GetAssignedQuestions(Question question, Int32 page, Int32 pageSize, ExpertSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestions(Question question, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                        ExpertSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestions(ExpertBase expert, Int32 page, Int32 pageSize, QuestionSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestions(ExpertBase expert, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                        QuestionSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestionsNotAnswered(Question question, Int32 page, Int32 pageSize, ExpertSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestionsNotAnswered(Question question, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                                   ExpertSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestionsNotAnswered(ExpertBase expert, Int32 page, Int32 pageSize, QuestionSortOrder[] order);

        AssignedQuestionCollection GetAssignedQuestionsNotAnswered(ExpertBase expert, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                                   QuestionSortOrder[] order);

        Answer AddAnswer(Answer answer);

        void UpdateAnswer(Answer answer);

        void RemoveAnswer(Answer answer);

        Answer GetAnswer(Int32 id);

        Answer GetAnswer(Question question, ExpertBase expert);

        AnswerCollection GetAnswers(Question question, Int32 page, Int32 pageSize, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(Question question, Int32 page, Int32 pageSize, out Int32 totalItems, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(Question question, AnswerStatus answerStatus, Int32 page, Int32 pageSize, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(Question question, AnswerStatus answerStatus, Int32 page, Int32 pageSize, out Int32 totalItems,
                                    AnswerSortOrder[] order);

        AnswerCollection GetAnswers(ExpertBase expert, Int32 page, Int32 pageSize, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(ExpertBase expert, Int32 page, Int32 pageSize, out Int32 totalItems, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(ExpertBase expert, AnswerStatus answerStatus, Int32 page, Int32 pageSize, AnswerSortOrder[] order);

        AnswerCollection GetAnswers(ExpertBase expert, AnswerStatus answerStatus, Int32 page, Int32 pageSize, out Int32 totalItems,
                                    AnswerSortOrder[] order);

        event EPiServerCommonEventHandler ExpertAdded;

        event EPiServerCommonEventHandler ExpertUpdated;

        event EPiServerCommonEventHandler ExpertRemoved;

        event EPiServerCommonEventHandler AnswerAdded;

        event EPiServerCommonEventHandler AnswerUpdated;

        event EPiServerCommonEventHandler AnswerRemoved;

        event EPiServerCommonEventHandler QuestionAdded;

        event EPiServerCommonEventHandler QuestionUpdated;

        event EPiServerCommonEventHandler QuestionRemoved;

        event EPiServerCommonEventHandler QuestionStatusChanged;

        event EPiServerCommonEventHandler AssignedQuestionAdded;

        event EPiServerCommonEventHandler AssignedQuestionRemoved;

        ExpertCollection GetQueryResult(ExpertQuery query);

        ExpertCollection GetQueryResult(ExpertQuery query, Int32 page, Int32 pageSize);

        ExpertCollection GetQueryResult(ExpertQuery query, Int32 page, Int32 pageSize, out Int32 totalItems);

        QuestionCollection GetQueryResult(QuestionQuery query);

        QuestionCollection GetQueryResult(QuestionQuery query, Int32 page, Int32 pageSize);

        QuestionCollection GetQueryResult(QuestionQuery query, Int32 page, Int32 pageSize, out Int32 totalItems);

        AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query);

        AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query, Int32 page, Int32 pageSize);

        AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query, Int32 page, Int32 pageSize, out Int32 totalItems);

        AnswerCollection GetQueryResult(AnswerQuery query);

        AnswerCollection GetQueryResult(AnswerQuery query, Int32 page, Int32 pageSize);

        AnswerCollection GetQueryResult(AnswerQuery query, Int32 page, Int32 pageSize, out Int32 totalItems);
    }
}